package com.gict.antifraudback.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gict.antifraudback.entity.Article;
import com.gict.antifraudback.entity.Question;
import com.gict.antifraudback.entity.QuestionOption;
import com.gict.antifraudback.exception.BusinessException;
import com.gict.antifraudback.mapper.QuestionMapper;
import com.gict.antifraudback.service.QuestionOptionService;
import com.gict.antifraudback.service.QuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question>
		implements QuestionService {
	
	@Autowired
	private QuestionMapper questionMapper;
	@Autowired
	private QuestionOptionService questionOptionService;

	@Override
	@Transactional
	public void createQuestions(List<Question> questions) {
		List<Question> updateList = new ArrayList<>();
		for (Question question : questions) {
			save(question);
			// 正确选项
			List<Integer> correctOptions = question.getCorrectOptions();
			// 选项
			List<String> questionoptions = question.getQuestionOptions();
			for (int i = 0; i < questionoptions.size(); i++) {
				QuestionOption questionoption = new QuestionOption();
				questionoption.setContent(questionoptions.get(i));
				questionoption.setQuestionId(question.getId());
				questionoption.setOptionIndex(i);
				questionOptionService.save(questionoption);
			}

			question.setAnswerIds(JSON.toJSONString(correctOptions));
			// 修改正确选项的id
			updateList.add(question);
		}
		// 修改试题
		updateBatchById(updateList);
	}

	@Override
	public Collection<Question> listByQuestionIds(List<String> ids) {
		Collection<Question> question = listByIds(ids);
		queryOptions(question);
		return question;
	}

	private void queryOptions(Collection<Question> questions) {
		if (CollectionUtils.isEmpty(questions)){
			return;
		}
		List<Integer> questionIds = questions.stream().map(Question::getId).collect(Collectors.toList());
		List<QuestionOption> questionoptions = questionOptionService.listByQuestions(questionIds);
		// 对题目的选项内容进行拼装
		if (!CollectionUtils.isEmpty(questionoptions)){
			Map<Integer, List<QuestionOption>> optionsMap = questionoptions.stream().collect(Collectors.groupingBy(QuestionOption::getQuestionId));
			for (Question question : questions) {
				List<QuestionOption> questionoptionList = optionsMap.get(question.getId());
				question.setCorrectOptions(JSON.parseArray(question.getAnswerIds(), Integer.class));
				if (!CollectionUtils.isEmpty(questionoptionList)){
					question.setQuestionOptions(questionoptionList.stream().sorted(Comparator.comparing(QuestionOption::getOptionIndex)).map(QuestionOption::getContent).collect(Collectors.toList()));
				}
			}
		}
	}

	/**
	 * 参数检查
	 * @param questions
	 */
	@Override
	public void checkParam(List<Question> questions) {
		if (CollectionUtils.isEmpty(questions)) {
			throw new BusinessException("题目不存在！");
		}

		for (Question question : questions) {
			if (ObjectUtils.isEmpty(question.getStatement())){
				throw new BusinessException("题干不能为空！");
			}
			if (CollectionUtils.isEmpty(question.getCorrectOptions())){
				throw new BusinessException("正确选项不能为空！");
			}
			if (CollectionUtils.isEmpty(question.getQuestionOptions())){
				throw new BusinessException("选项不能为空;");
			}
			for (String option : question.getQuestionOptions()) {
				if (ObjectUtils.isEmpty(option)){
					throw new BusinessException("选项不能为空值！");
				}
			}
			// 判断不同类型的题目校验 TODO
		}
	}

	@Override
	public void removeQuestionAndOptionByArticleId(Integer id) {
		List<Question> list = list(Wrappers.<Question>lambdaQuery().eq(Question::getArticleId, id));
		if (!CollectionUtils.isEmpty(list)){
			List<Integer> questionIds = list.stream().map(Question::getId).collect(Collectors.toList());
			LambdaQueryWrapper<QuestionOption> optionRemoveWrapper = Wrappers.lambdaQuery();
			optionRemoveWrapper.in(QuestionOption::getQuestionId, questionIds);
			// 删除选项
			questionOptionService.remove(optionRemoveWrapper);
			// 删除题目
			removeByIds(questionIds);
		}
	}

	@Override
	public List<Question> listQuestionByArticleId(Integer id) {
		Collection<Question> question = list(Wrappers.<Question>lambdaQuery().eq(Question::getArticleId, id));
		queryOptions(question);
		if (!CollectionUtils.isEmpty(question)){
			return new ArrayList<>(question);
		}else {
			return new ArrayList<>();
		}
	}

	@Override
	public List<Question> everydayExercise() {
		QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
		queryWrapper.orderByAsc("RAND()").last("LIMIT 10");
		List<Question> list = list(queryWrapper);
		queryOptions(list);
		return list;
	}
}
